#define versionInfo "zxx 2013903 v22"

#include "commons.h"
#include "tasks.h"
#include "zxLib.h"
#include "ldLib.h"
#include "HZLib.h"
#include "cq.h"

_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV20 & PWRT_64 & MCLR_EN);

int main(void) {
    ADPCFG = 0xFFFF;
    SetupPorts();
    Init_LCD();
    Init_PWM();
    InitUART2();
    Init_Keypad();
    InitTMR2();
    InitTMR3();
    Flags.pun = 0;
    Flags.punable = 1;
    unsigned char StartText[] = {0x55, 0x00, 0x01, 0xAA};
    Puts_UART2((unsigned char*) &StartText[0], sizeof (StartText));

    home_clr();
    LCDWriteString("Happy Train Mice");
    line_2();
    LCDWriteString(versionInfo);
    DelayNmSecNew(1000);


    while (1) {
        unsigned int n = getFuncNumber(4, "Main Function ?");
        srand((unsigned) time(NULL));

        switch (n) {
            case 1002:
                test_odorA();
                break;
            case 1003:
                test_odorB();
                break;
            case 1004:
                test_odorC();
                break;
            case 1005:
                test_odorD();
                break;
            case 1006:
                test_odorE();
                break;
            case 1008:
                test_BNC();
                break;
            case 1009:
                test_lick();
                break;
            case 1010:
                auto_AB_BA_Go_AA_BB_Nogo_Ran_onebacktest(4, 10, 20, 0.5, 50, 50, 1);
                break;
            case 1011:
                AB_BA_Go(2, 5, 0.5);
                break;
            case 1012:
                AB_BA_Go(4, 10, 0.5);
                break;
            case 1013:
                AB_BA_Go(2, 5, 0.0);
                break;
            case 1014:
                AB_BA_Go(4, 10, 0.0);
                break;
            case 1015:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(4, 10, 20, 0.5, 6, 10, 1.0);
                break;
            case 1016:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(4, 10, 20, 0.5, 6, 50, 0.0);
                break;
            case 1017:
                break;
            case 1018:
                break;
            case 1019:
                break;
            case 1020:
                break;
            case 1021:
                AA_BB_Go(2, 5, 0.5);
                break;
            case 1022:
                auto_AA_BB_Go_AB_BA_Nogo_Ran(4, 10, 20, 0.5, 6, 10, 1.0);
                break;
            case 1023:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(4, 10, 20, 0.2, 6, 10, 1.0);
                break;
            case 1024:
                auto_AA_BB_Go_AB_BA_Nogo_Ran(4, 10, 20, 0.2, 6, 10, 1.0);
                break;
            case 1025:
                rule_switch_MNM(4, 10, 20, 0.5, 80, 30, 1);
                break;
            case 1026:
                rule_switch_NMN(4, 10, 20, 0.5, 80, 30, 1);
                break;
            case 1031:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(4, 10, 8, 8, 8, 1, 1000);
                break;
            case 1032:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(8, 14, 8, 8, 8, 1, 1000);
                break;
            case 1033:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(12, 18, 8, 8, 8, 1, 1000);
                break;
            case 1034:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(4, 10, 8, 8, 8, 1, 1000);
                break;
            case 1035:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(8, 14, 8, 8, 8, 1, 1000);
                break;
            case 1036:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(12, 18, 8, 8, 8, 1, 1000);
                break;
            case 1037:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(4, 10, 8, 8, 8, 1, 1000);
                break;
            case 1038:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(8, 14, 8, 8, 8, 1, 1000);
                break;
            case 1039:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(12, 18, 8, 8, 8, 1, 1000);
                break;
            case 1041:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(4, 10, 8, 8, 8, 20, 5);
                break;
            case 1042:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(8, 14, 8, 8, 8, 20, 5);
                break;
            case 1043:
                AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(12, 18, 8, 8, 8, 20, 5);
                break;
            case 1044:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(4, 10, 8, 8, 8, 20, 5);
                break;
            case 1045:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(8, 14, 8, 8, 8, 20, 5);
                break;
            case 1046:
                AB_BA_Go_AA_BB_Nogo_Ran_odor(12, 18, 8, 8, 8, 20, 5);
                break;
            case 1047:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(4, 10, 8, 8, 8, 20, 5);
                break;
            case 1048:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(8, 14, 8, 8, 8, 20, 5);
                break;
            case 1049:
                AB_BA_Go_AA_BB_Nogo_Ran_ITI(12, 18, 8, 8, 8, 20, 5);
                break;
            case 1050:
                AB_BA_Go_AA_BB_Nogo_Ran_8DFir4(4, 10, 8, 8, 8, 1, 1000);
                break;
            case 1051:
                AB_BA_Go_AA_BB_Nogo_Ran_8DMid4(8, 14, 8, 8, 8, 1, 1000);
                break;
            case 1052:
                AB_BA_Go_AA_BB_Nogo_Ran_8DLas4(12, 18, 8, 8, 8, 1, 1000);
                break;
            case 1053:
                AB_BA_Go_AA_BB_Nogo_Ran_8DFir4(4, 10, 8, 8, 8, 20, 5);
                break;
            case 1054:
                AB_BA_Go_AA_BB_Nogo_Ran_8DMid4(8, 14, 8, 8, 8, 20, 5);
                break;
            case 1055:
                AB_BA_Go_AA_BB_Nogo_Ran_8DLas4(12, 18, 8, 8, 8, 20, 5);
                break;
            case 1061:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(4, 10, 20, 0.5, 50, 50, 1.0);
                break;
            case 1062:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(8, 14, 20, 0.5, 50, 50, 1.0);
                break;
            case 1063:
                auto_AB_BA_Go_AA_BB_Nogo_Ran(12, 18, 20, 0.5, 50, 50, 1.0);
                break;
            case 1065:
                CQ_auto_AB_BA_Go_AA_BB_Nogo_Ran(4, 10, 20, 0.5, 6, 50, 1.0);
                break;
            case 1066:
                CQ_auto_AA_BB_Go_AB_BA_Nogo_Ran(4, 10, 20, 0.5, 6, 50, 1.0);
                break;
            case 1067:
                YWJ_AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(4.0, 10, 8, 8, 8, 20, 20, 0.5, 0.0);
                break;
            case 1068:
                YWJ_AB_BA_Go_AA_BB_Nogo_Ran_blue_delay(4.0, 10, 8, 8, 8, 20, 20, 0.0, 0.5);
                break;
            case 1069:
                test_odorAB();
                break;
            case 1070:
                //air_Lick(2, 5, 20, 1.0, 50, 10, 0.1);
                break;
            case 1071:
                //air_AB_BA_Go(2, 5, 1, 0.5);
                break;
            case 1072:
                //air_Clear(2, 5, 20, 1.0, 0.1, 50, 10);
                break;
            case 1073:
                //air_DNMS(2, 5, 20, 1.0, 0.1, 50, 10);
                break;
            case 1074:
                //air_DNMS2(2, 5, 18, 1.0, 0.1, 50, 10);
                break;
            case 1075:
                //air_Go_Nogo(2, 5, 20, 1.0, 50, 10, 0.1);
                break;
            case 1076:
                AB_BA_Go2(2, 5, 0.0);
                break;
            case 1077:
                auto_AB_BA_Go_AA_BB_Nogo_Ran2(2, 10, 8, 1.0, 10, 20, 0.0);
                break;
            case 1111:
                n = getFuncNumber(1, " 2  5  10 30 600");
                feedWater(n);
                break;
            case 1124:
                n = getFuncNumber(1, "IntOdr 1=4s 2=2s");
                if (n == 2) {
                    AB_BA_Go(2, 5, 0.5);
                } else {
                    AB_BA_Go(4, 10, 0.5);
                }
                break;

            case 1352:
                odorDepeltion(500);
                break;


                ///////Ld functions
            case 1511:
                LD_shaping_AB_BA_Go(3.0, 5, 1.0, 1.0); // for normal training
                //  LD_shaping_AB_BA_Go(float thisdelay, int ITI, float waterlen, float delay2)
                break;
            case 1512:
                LD_shaping_AB_BA_Go(5.0, 10, 0.5, 1.0); // for normal training
                break;
            case 1513:
                LD_shaping_AB_BA_Go(3.0, 5, 1.0, 0.0); // for dual task
                break;
            case 1514:
                LD_shaping_AB_BA_Go(5.0, 10, 1.0, 0.0); // for dual task
                break;

            case 1515:
                LD_auto_AB_BA_Go_AA_BB_Nogo_Ran_new(5.0, 10, 20, 0.5, 1.0, 6, 10); // for normal training
                //LD_auto_AB_BA_Go_AA_BB_Nogo_Ran_new(float thisdelay, int interti, int trialNumperSess, float waterlen, float delay2, int missstop, int sessstop)
                break;
            case 1521:
                LD_auto_AB_BA_Go_AA_BB_Nogo_Ran_new(5.0, 10, 20, 1.0, 0.0, 6, 10); // for dual task
                break;

            case 1522:
                CD_Go_Nogo(0.5, 5.0, 20, 1.0, 10, 10, 0.0);
                //CD_Go_Nogo(float thisdelay, float interti, int trialNumperSess, float WaterLen, int missstop, int sessstop, float delay_before_reward)
                break;
            case 1523:
                auto_AB_BA_Go_AA_BB_Nogo_Ran2(1.0, 10.0, 8.0, 1.0, 10.0, 40.0, 0.0);
                //auto_AB_BA_Go_AA_BB_Nogo_Ran2(float thisdelay, float interti, float trialNumperSess, float WaterLen, float missstop, float sessstop, float delay_before_reward)
                break;
                /////////////CQ functions//////////////////
            case 2111:
                n = getFuncNumber(1, "BGo1 JGo2 Rand");
                int m = getFuncNumber(1, "NL1 O2 D3 W4 I5");
                CQ_go_nogo_autoSwitch(n, m, 20, odor_A, odor_B, 0.5, 1.5, 0.5, 4); //deliver laser during the middle of delay
                break;
                //////////////HZ functions/////////////
            case 2511:
                HZ_Go_Nogo(0.5, 5.0, 20, 1.0, 10, 10, 0.0);
                break;
            case 2512:
                DualTask(1.0, 10.0, 8.0, 1.0, 10.0, 40.0, 0.0);
                break;
            case 2513:
                HZ_AB_BA_Go_AA_BB_Nogo_laser_ITI(4, 10, 20, 0.5, 50, 5, 1.0, 4, 2);
                break;
            case 2514:
                HZ_AB_BA_Go_AA_BB_Nogo_laser(4, 10, 20, 0.5, 50, 5, 1.0, 0, 4);
                break;
                ////////////////LD functions/////////////

                break;
            case 3355:
                pico(100, 900);
                break;

                //zx's menu
            case 4311:
                n = getFuncNumber(1, "OdrLen 1=0.5 2=1");
                setOdorLength(n == 1 ? 0.5 : 1);
                n = getFuncNumber(1, "AGo1 BGo2 Rand3");
                zxGo_nogo_autoSwitch(n, 20, odor_A, odor_B, 1, 0.5, 4, 0, 0, 1, 0, 0);
                break;
            case 4411:
                n = getFuncNumber(1, "1=AutoStop 2=No");
                setAutoStop(n == 1 ? 1 : 0);
                n = getFuncNumber(1, "OdrLen 1=0.5 2=1");
                setOdorLength(n == 1 ? 0.5 : 1);
                n = getFuncNumber(1, "IntOdr 1=8s 2=5s");
                if (n == 2) {
                    zxDNMSSessions(5.0, 10, 20, 0.5, 1.0, 100, 40);
                } else {
                    zxDNMSSessions(8.5, 20, 20, 0.5, 1.0, 100, 40);
                }
                break;
            case 4412:
                n = getFuncNumber(1, "OdrLen 1=0.5 2=1");
                setOdorLength(n == 1 ? 0.5 : 1);
                n = getFuncNumber(1, "IntOdr 1=8s 2=5s");
                if (n == 2) {
                    zxDNMSLaserSessions(laserInDelay, 5.0, 10, 20, 0.5, 50, 12, 1.0, 1.0, 4.0);
                } else {
                    zxDNMSLaserSessions(laserInDelay, 8.5, 20, 20, 0.5, 50, 12, 1.0, 1.0, 4.0);
                }
                break;
            case 4413:
                n = getFuncNumber(1, "OdrLen 1=0.5 2=1");
                setOdorLength(n == 1 ? 0.5 : 1);
                n = getFuncNumber(1, "IntOdr 1=8s 2=5s");
                if (n == 2) {
                    zxDNMSLaserSessions(laserDuringOdor, 5.0, 10, 20, 0.5, 50, 12, 1.0, 1.0, 4.0);
                } else {
                    zxDNMSLaserSessions(laserDuringOdor, 8.5, 20, 20, 0.5, 50, 12, 1.0, 1.0, 4.0);
                }
                break;


                //Shared Utility
            case 5555:
                odorDepeltion(120);
                break;

        }
    }
}

